//! Simplified Actor message definitions
//! 
//! This module defines all the message types used for communication
//! between actors in the system.

use crate::models::{
    testcase::TestCase,
    config::{TestConfig, StepConfig},
    step::{StepResult, StepContext},
    summary::{TestSummary, TestCaseSummary},
    plugin::{PluginInfo, PluginManifest},
    ai::{AIPrompt, AIResponse as AIResponseModel},
    Value, ValueMap,
};
use coerce::actor::message::Message;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use uuid::Uuid;

// ============================================================================
// Test Suite Actor Messages
// ============================================================================

/// Messages for TestSuiteActor
#[derive(Debug, Clone)]
pub enum TestSuiteMessage {
    /// Load a test suite from file or directory
    LoadTestSuite { path: String },
    
    /// Execute a test suite
    ExecuteSuite { suite_id: Uuid, config: TestConfig },
    
    /// Get test suite status
    GetSuiteStatus { suite_id: Uuid },
    
    /// Stop test suite execution
    StopExecution { suite_id: Uuid },
    
    /// List all test suites
    ListSuites,
}

impl Message for TestSuiteMessage {
    type Result = TestSuiteResponse;
}

/// Responses from TestSuiteActor
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TestSuiteResponse {
    /// Test suite loaded successfully
    SuiteLoaded { suite_id: Uuid, test_cases: Vec<TestCase> },
    
    /// Test suite execution started
    ExecutionStarted { execution_id: Uuid },
    
    /// Test suite execution completed
    ExecutionCompleted { execution_id: Uuid, summary: TestSummary },
    
    /// Test suite status information
    StatusInfo { suite_id: Uuid, status: ExecutionStatus, progress: ExecutionProgress },
    
    /// List of test suites
    SuiteList { suites: Vec<TestSuiteInfo> },
    
    /// Error occurred
    Error { message: String },
}

// ============================================================================
// Session Actor Messages
// ============================================================================

/// Messages for SessionActor
#[derive(Debug, Clone)]
pub enum SessionMessage {
    /// Start a test session
    StartSession { test_case: TestCase, parameters: ValueMap },
    
    /// Update session variables
    UpdateVariables { variables: ValueMap },
    
    /// Get session summary
    GetSessionSummary,
    
    /// Stop session execution
    StopSession,
}

impl Message for SessionMessage {
    type Result = SessionResponse;
}

/// Responses from SessionActor
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SessionResponse {
    /// Session started successfully
    SessionStarted { session_id: Uuid },
    
    /// Session completed
    SessionCompleted { session_id: Uuid, summary: TestCaseSummary },
    
    /// Session summary
    SessionSummary { summary: TestCaseSummary },
    
    /// Error occurred
    Error { message: String },
}

// ============================================================================
// Plugin Actor Messages
// ============================================================================

/// Messages for PluginActor
#[derive(Debug, Clone)]
pub enum PluginMessage {
    /// Load a plugin
    LoadPlugin { path: String, config: ValueMap },
    
    /// Call a plugin function
    CallFunction { plugin_id: String, function_name: String, args: Vec<Value> },
    
    /// Unload a plugin
    UnloadPlugin { plugin_id: String },
    
    /// List all plugins
    ListPlugins,
    
    /// Get plugin information
    GetPluginInfo { plugin_id: String },
}

impl Message for PluginMessage {
    type Result = PluginResponse;
}

/// Responses from PluginActor
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PluginResponse {
    /// Plugin loaded successfully
    PluginLoaded { plugin_id: String, manifest: PluginManifest },
    
    /// Function call result
    FunctionResult { result: Value },
    
    /// Plugin unloaded
    PluginUnloaded { plugin_id: String },
    
    /// List of plugins
    PluginList { plugins: Vec<PluginInfo> },
    
    /// Plugin information
    PluginInfo { info: PluginInfo },
    
    /// Error occurred
    Error { message: String },
}

// ============================================================================
// AI Orchestration Actor Messages
// ============================================================================

/// Messages for AIOrchestrationActor
#[derive(Debug, Clone)]
pub enum AIMessage {
    /// Generate test case from specification
    GenerateTestCase { specification: Value, context: ValueMap },
    
    /// Analyze test failure
    AnalyzeFailure { failure: StepResult, context: ValueMap },
    
    /// Optimize test suite
    OptimizeSuite { suite: TestSummary, metrics: ValueMap },
    
    /// Generate assertions for response
    GenerateAssertions { response: Value, context: ValueMap },
    
    /// Process custom AI prompt
    ProcessPrompt { prompt: AIPrompt },
}

impl Message for AIMessage {
    type Result = AIResponse;
}

/// Responses from AIOrchestrationActor
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AIResponse {
    /// Test case generated
    TestCaseGenerated { test_case: TestCase, confidence: f32 },
    
    /// Failure analysis completed
    FailureAnalyzed { analysis: Value, suggestions: Vec<String> },
    
    /// Suite optimization completed
    SuiteOptimized { optimizations: Vec<Value>, estimated_improvement: f32 },
    
    /// Assertions generated
    AssertionsGenerated { assertions: Vec<Value>, confidence: f32 },
    
    /// Prompt processed
    PromptProcessed { response: AIResponseModel },
    
    /// Error occurred
    Error { message: String },
}

// ============================================================================
// Step Actor Messages
// ============================================================================

/// Messages for StepActor
#[derive(Debug, Clone)]
pub enum StepMessage {
    /// Execute a test step
    ExecuteStep { step_config: StepConfig, context: StepContext },

    /// Validate step result
    ValidateResult { result: StepResult, validators: ValueMap },

    /// Extract variables from result
    ExtractVariables { result: StepResult, extractors: HashMap<String, String> },
}

impl Message for StepMessage {
    type Result = StepResponse;
}

/// Responses from StepActor
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum StepResponse {
    /// Step executed successfully
    StepExecuted { result: StepResult },

    /// Validation completed
    ValidationCompleted { success: bool, errors: Vec<String> },

    /// Variables extracted
    VariablesExtracted { variables: ValueMap },

    /// Error occurred
    Error { message: String },
}

// ============================================================================
// Report Actor Messages
// ============================================================================

/// Messages for ReportActor
#[derive(Debug, Clone)]
pub enum ReportMessage {
    /// Add step result to report
    AddStepResult { result: StepResult },
    
    /// Generate HTML report
    GenerateHTMLReport { summary: TestSummary, output_path: String },
    
    /// Export results in specified format
    ExportResults { summary: TestSummary, format: ExportFormat, output_path: String },
    
    /// Get test statistics
    GetStatistics,
}

impl Message for ReportMessage {
    type Result = ReportResponse;
}

/// Responses from ReportActor
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ReportResponse {
    /// Step result added
    StepResultAdded,
    
    /// HTML report generated
    HTMLReportGenerated { report_path: String },
    
    /// Results exported
    ResultsExported { export_path: String },
    
    /// Test statistics
    Statistics { stats: ValueMap },
    
    /// Error occurred
    Error { message: String },
}

// ============================================================================
// Supporting Types
// ============================================================================

/// Execution status
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ExecutionStatus {
    Pending,
    Running,
    Completed,
    Failed,
    Cancelled,
}

/// Execution progress
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExecutionProgress {
    pub total_steps: usize,
    pub completed_steps: usize,
    pub failed_steps: usize,
    pub current_step: Option<String>,
}

/// Test suite information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TestSuiteInfo {
    pub id: Uuid,
    pub name: String,
    pub path: String,
    pub test_case_count: usize,
    pub status: ExecutionStatus,
}

/// Export formats
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ExportFormat {
    HTML,
    JSON,
    XML,
    PDF,
    CSV,
}

impl ExecutionProgress {
    /// Create new execution progress
    pub fn new(total_steps: usize) -> Self {
        Self {
            total_steps,
            completed_steps: 0,
            failed_steps: 0,
            current_step: None,
        }
    }
    
    /// Calculate completion percentage
    pub fn completion_percentage(&self) -> f32 {
        if self.total_steps == 0 {
            return 100.0;
        }
        (self.completed_steps as f32 / self.total_steps as f32) * 100.0
    }
    
    /// Check if execution is complete
    pub fn is_complete(&self) -> bool {
        self.completed_steps + self.failed_steps >= self.total_steps
    }
}
